import { Reporter } from './reporter';
import { PerformanceSubType } from '../types';

interface LargestContentfulPaint extends PerformanceEntry {
  element: HTMLElement | null;
  startTime: number;
}

interface PerformanceLayoutShift extends PerformanceEntry {
  value: number;
  hadRecentInput: boolean;
}

export class PerformanceMonitor {
  private reporter: Reporter;

  constructor(reporter: Reporter) {
    this.reporter = reporter;
    this.init();
  }

  /**
   * 初始化性能监控
   */
  init() {
    // 页面加载完成后收集加载指标
    if (document.readyState === 'complete') {
      this.collectLoadMetrics();
    } else {
      window.addEventListener('load', () => this.collectLoadMetrics());
    }

    // 监控Core Web Vitals
    this.observeCoreWebVitals();
  }

  /**
   * 收集页面加载指标
   */
  private collectLoadMetrics() {
    // 关键修改：类型断言，包含 navigationStart 等属性
    const perfData = performance.getEntriesByType('navigation')[0] as PerformanceTiming & PerformanceNavigationTiming;
    if (!perfData) return;

    // 后续代码不变...
    const metrics = {
      type: 'performance' as const, // 后续解决type问题时会用到
      subType: 'page_load' as PerformanceSubType,
      whiteScreenTime: perfData.responseStart - perfData.navigationStart, // 现在不会报错
      fcpTime: this.getFCPTime(),
      domReadyTime: perfData.domContentLoadedEventEnd - perfData.navigationStart,
      loadTime: perfData.loadEventEnd - perfData.navigationStart,
      firstScreenTime: perfData.domContentLoadedEventEnd - perfData.navigationStart,
      navigationType: perfData.type
    };

    this.reporter.push(metrics);
  }

  /**
   * 获取FCP（首次内容绘制）时间
   */
  private getFCPTime(): number {
    const fcpEntries = performance.getEntriesByName('first-contentful-paint');
    return fcpEntries.length > 0 ? (fcpEntries[0] as PerformanceEntry).startTime : 0;
  }

  /**
   * 监控Core Web Vitals（LCP、FID、CLS）
   */
  private observeCoreWebVitals() {
    if (!('PerformanceObserver' in window)) return;

    // 监听 LCP（关键修改：断言为 LargestContentfulPaint）
    new PerformanceObserver((entries) => {
      // 将 entry 断言为 LargestContentfulPaint 类型
      const lcpEntry = entries.getEntries()[0] as LargestContentfulPaint;
      this.reporter.push({
        type: 'performance' as const,
        subType: 'lcp' as PerformanceSubType,
        value: lcpEntry.startTime,
        // 现在可安全访问 element 属性
        element: lcpEntry.element?.tagName.toLowerCase() || 'unknown'
      });
    }).observe({ type: 'largest-contentful-paint', buffered: true });

    // 2. CLS（累积布局偏移）
    let clsValue = 0;
    new PerformanceObserver((entries) => {
      // 1. 用 getEntries() 获取数组，避免 forEach 类型问题
      const clsEntries = entries.getEntries() as PerformanceLayoutShift[];
      // 2. 遍历数组，显式指定 entry 类型为 PerformanceLayoutShift
      clsEntries.forEach((entry: PerformanceLayoutShift) => {
        if (!entry.hadRecentInput) {
          clsValue += entry.value;
          this.reporter.push({
            type: 'performance' as const,
            subType: 'cls' as PerformanceSubType,
            value: clsValue
          });
        }
      });
    }).observe({ type: 'layout-shift', buffered: true });
  }
}